/*============================================================================*/
/*                        Tortoise Team			                              */
/*============================================================================*/
/*                        OBJECT SPECIFICATION                                */
/*============================================================================*
* C Source:         %HAL_Linear_Camera.c%
* Instance:         RPL_1
* %version:         1.1 %
* %created_by:      Andres Torres Garcia %
* %date_created:    Satur Sep 15 09:13:01 2012 %
*=============================================================================*/
/* DESCRIPTION : Define and declare the functions of the hardware layer of the*/
/*				 Linear Camera			                                      */
/*============================================================================*/
/* FUNCTION COMMENT : Source file of the hardware abstraction layer of the	  */
/*					  Linear Camera                                           */
/*                                                                            */
/*============================================================================*/
/*                               OBJECT HISTORY                               */
/*============================================================================*/
/*  REVISION |   DATE      |                               |      AUTHOR      */
/*----------------------------------------------------------------------------*/
/*  1.0      | 15/09/2012  | SAR/SIF/SCN_xxx               | Andres Torres    */
/*  1.1      | 11/10/2012  | SAR/SIF/SCN_xxx               | Andres Torres    */
/*  1.2      | 13/11/2012  | SAR/SIF/SCN_xxx               | Andres Torres    */
/* Integration under Continuus CM                                             */
/*============================================================================*/

/* Includes */
/* -------- */
#include "MAL_PWM.h"
#include "MAL_ADC.h"
#include "MAL_EMIOS.h"
#include "MAL_IOAPI.h"
#include "HAL_Linear_Camera.h"

/* Functions macros, constants, types and datas         */
/* ---------------------------------------------------- */
/* Functions macros */

/*==================================================*/ 
/* Definition of constants                          */
/*==================================================*/ 


/*======================================================*/ 
/* Definition of RAM variables                          */
/*======================================================*/

/** \brief The last updated pixels of the Linear Camera */
T_SWORD sw_Pixels[NUM_PIXELS]; 

/*======================================================*/ 
/* close variable declaration sections                  */
/*======================================================*/ 

/* Private defines */

/*!
  \def PIN_DEBUG
  Pin for debug purposes.
*/
#define PIN_DEBUG	1
//#define DEBUG

/*!
  \def PIX_LOSS
  Pixels lost due to the noise filter.
*/
#ifdef NOISE_FILTER_PRESENT

	#define PIX_LOSS	2
	
#elif defined (FREESCALE_CAMERA)

	#define PIX_LOSS	5

#endif

/* Private functions prototypes */
/* ---------------------------- */


/* Exported functions prototypes */
/* ----------------------------- */

void vfnInitCamera(void);
void vfnCapturePixels(void);
void vfnStopCamera(void);
void vfnStartCamera(void);
void vfnStartCapturing(void);
void vfnStopCapturing(void);
void vfnInterrupToCapturePix(void);

/* Inline functions */
/* ---------------- */

/* Private functions */
/* ----------------- */

/* Exported functions */
/* ------------------ */

/**************************************************************
 *  Name                 : vfnInitCamera
 *  Description          :	Initialize the linear camera.
 *  Parameters           :  [Input; Output; Input / output]
 *  Return               :	void
 *  Critical/explanation :    No
 **************************************************************/
///////////////////////////////////////////////////////////////////////
/// \brief Initialize the Linear Camera
/////////////////////////////////////////////////////////////////////////
void vfnInitCamera(void)
{
	//TODO: It has to be set up in another part. When you join all the code.
	vfnSetUpClock();
	
	//Mapping the EMIOS channeles to different pins.
	IO_ChangeFctnPin(13, 1);
	IO_ChangeFctnPin(15, 1);

	vfnInitPWM_Out_Of_Phase(CHANNEL_CK, CLK_PERIOD / 4, (3 * CLK_PERIOD) / 4, CHANNEL_CNT_CK, CLK_PERIOD, COUNTER_BUS_A, PIN_CK);
	vfnInitPWM_Out_Of_Phase(CHANNEL_TRIG_ADC, 0, CLK_PERIOD / 2, CHANNEL_CNT_TRIG_ADC, CLK_PERIOD, COUNTER_BUS_A, PIN_TRIG_ADC);
	vfnEnable_Int_Ctu(CHANNEL_TRIG_ADC);
	vfnEnable_Ctu_Flag(CHANNEL_TRIG_ADC);
	
	vfnInitPWM_Out_Of_Phase(CHANNEL_SI, 0, CLK_PERIOD / 2, CHANNEL_CNT_SI, SI_PERIOD, COUNTER_BUS_BCDE, PIN_SI);
	vfnInitPWM_Out_Of_Phase(CHANNEL_TRIG, 19992, 19994, CHANNEL_CNT_TRIG, SI_PERIOD, COUNTER_BUS_BCDE, PIN_TRIG);
	
	vfnConfigPinAs_ADC_Channel(ANP_PCR_2);
	vfnConfig_ADC_Mode(SCAN);
	//ADC.MCR.B.CTUEN = 1;
	vfnJustifiedADCread(RIGHT);
	vfnSetConvertionTime( 0, _32_MHz );
	
	//vfnEnable_Trigger_Emios_Adc(CHANNEL_TRIG_ADC, CTU_CHANNEL_ANP2);
	
	/*vfnEnable_Adc_Cross_Trigger();
	vfnEnable_Trigger_Emios_Adc(CHANNEL_TRIG_IN,CTU_CHANNEL_ANP0);
	*///TODO: Check which works
	//vfnEnable_Adc_Ctu_Interrupt();
	/*vfnEnable_Adc_SingleShot_Interrupt();
	
	ENABLE_INT_ADC_CHN0(ADC_PRECISION_CHANNEL);*/
}

/**************************************************************
 *  Name                 : vfnStopCamera
 *  Description          :	Stop the linear camera.
 *  Parameters           :  [Input; Output; Input / output]
 *  Return               :	void
 *  Critical/explanation :    No
 **************************************************************/
///////////////////////////////////////////////////////////////////////
/// \brief Stop the Linear Camera
/////////////////////////////////////////////////////////////////////////
void vfnStopCamera(void)
{
	vfnSetDutyCycle(CHANNEL_CK, CLK_PERIOD / 4);
	vfnSetDutyCycle(CHANNEL_SI, 0);
	vfnSetDutyCycle(CHANNEL_TRIG, 19992);
}

/**************************************************************
 *  Name                 : vfnStartCamera
 *  Description          :	Start the linear camera.
 *  Parameters           :  [Input; Output; Input / output]
 *  Return               :	void
 *  Critical/explanation :    No
 **************************************************************/
///////////////////////////////////////////////////////////////////////
/// \brief Start the Linear Camera
/////////////////////////////////////////////////////////////////////////
void vfnStartCamera(void)
{
	vfnSetDutyCycle(CHANNEL_CK, (3 * CLK_PERIOD) / 4);
	vfnSetDutyCycle(CHANNEL_SI, CLK_PERIOD / 2);
	vfnSetDutyCycle(CHANNEL_TRIG, 19994);
}

/**************************************************************
 *  Name                 : vfnStartCapturing
 *  Description          :	Start capturing the pixels of the linear camera.
 *  Parameters           :  [Input; Output; Input / output]
 *  Return               :	void
 *  Critical/explanation :    No
 **************************************************************/
///////////////////////////////////////////////////////////////////////
/// \brief Start capturing pixels from the Linear Camera.
/////////////////////////////////////////////////////////////////////////
void vfnStartCapturing(void)
{
	//ADC.MCR.B.CTUEN = 1;
	
	vfnEnable_Trigger_Emios_Adc(CHANNEL_TRIG_ADC, CTU_CHANNEL_ANP2);

	vfnEnable_Int_Ctu(CHANNEL_CNT_SI);
	vfnEnable_Int_Ctu(CHANNEL_TRIG);
}

/**************************************************************
 *  Name                 : vfnStopCapturing
 *  Description          :	Stop capturing the pixels of the linear camera.
 *  Parameters           :  [Input; Output; Input / output]
 *  Return               :	void
 *  Critical/explanation :    No
 **************************************************************/
///////////////////////////////////////////////////////////////////////
/// \brief Stop capturing pixels from the Linear Camera.
/////////////////////////////////////////////////////////////////////////
void vfnStopCapturing(void)
{
	vfnDisable_Int_Ctu(CHANNEL_CNT_SI);
	vfnDisable_Int_Ctu(CHANNEL_TRIG);
}

/**************************************************************
 *  Name                 : vfnCapturePixels
 *  Description          :	Capture the pixels of the linear camera.
 *  Parameters           :  [Input; Output; Input / output]
 *  Return               :	void
 *  Critical/explanation :    No
 **************************************************************/
///////////////////////////////////////////////////////////////////////
/// \brief Capture 128 pixels of the Linear Camera.
/////////////////////////////////////////////////////////////////////////
void vfnCapturePixels(void)
{
	T_UBYTE counter = 0;
	T_UBYTE i;
	
	#ifdef RETARD
	
		for( i = 0; i < PIX_LOSS; i++)
	    {
	    	while(!ADCConvertionComplete(ANP_2)) {};     /* Wait for last scan to complete */
	    	ADCReadValue(ANP_2);			 /* Read ANP0 conversion result data */
	    }
	    
	#else
		    while(!ADCConvertionComplete(ANP_2)) {};     /* Wait for last scan to complete */
			ADCReadValue(ANP_2);			 /* Read ANP0 conversion result data */
	
	#endif
    
    #ifdef DEBUG
    
    	IO_ToggleOutput(PIN_DEBUG);
    
    #endif
	
	while(counter < NUM_PIXELS)
	{    	
    	while (!ADCConvertionComplete(ANP_2)) {};     /* Wait for last scan to complete */
    	sw_Pixels[counter] = ADCReadValue(ANP_2);			 /* Read ANP0 conversion result data */
    	
    	counter++;
	}
	
	#ifdef DEBUG
	
		IO_ToggleOutput(PIN_DEBUG);
	
	#endif
}

/**************************************************************
 *  Name                 : vfnInterrupToCapturePix
 *  Description          :	Interruption to capture the pixels of the Linear Camera.
 *  Parameters           :  [Input; Output; Input / output]
 *  Return               :	void
 *  Critical/explanation :    No
 **************************************************************/
///////////////////////////////////////////////////////////////////////
/// \brief Interruption to capture the pixels of the Linear Camera.
/////////////////////////////////////////////////////////////////////////
void vfnInterrupToCapturePix(void)
{	
	vfnCapturePixels();
	
	//Stop the clock
	//vfnSetDutyCycle(CHANNEL_CK, CLK_PERIOD / 4);
	
	//Stop the ADC trigger convertion.
	vfnSetDutyCycle(CHANNEL_TRIG_ADC, 0);
}